/*
 * Floatacious: Better floating in IE5/6/7
 * Copyright 2010 B@NG!
 * http://code.google.com/p/stan-js/#Floatacious
 * Available for use under the MIT license
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Includes portions of jQuery
 * Copyright John Resig
 * http://jquery.com/
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 */

 (function() {

  /* Fix floats in old IEs */

  ver = {
    version: "0.1",
    timestamp: "Fri, Jun 04 2010 16:36:39 GMT"
  };

  // TODO: fl.destroy();

  /*
   * Public method floatacious()
   *
   * my:             The element to correct (document.body is used if nothing is passed)
   *                 If passed a function, it will be called after Floatacious has fixed the document
   * instant:        Passing true will not set a timeout to correct floats
   * deep:           Depth of the element in the DOM
   * force:          Passing true will force a calc
   */
  fl = floatacious = window.floatacious = function(my, instant, deep, force) {

    fl.run = fl.run || 0;

    if (fl.stopped) return;

    if (typeof my === 'function') {
      fl.callback = my; // set as callback from now on
      my = null;
    }

    if (!my) {
      // Fix entire document
      if (fl.floating) { // floatacious is already at work
        fl.queued = true;
        return;
      }
      fl.floating = true;
      my = document.body;
    }

    deep = deep || 0;

    // get the original currentStyle value for an element style property
    function o(m,g) {
      if (m['fl_' + g + 's']) return m['fl_' + g + 's'];
      if (m['fl_' + g] && m['fl_' + g] !== 'fl_null') return m['fl_' + g];
      switch (g) {
      case 'fl': return fl.getStyle(m,'styleFloat');
      case 'ds': return fl.getStyle(m,'display');
      case 'cl': return fl.getStyle(m,'clear');
      case 'ta': return fl.getStyle(m,'textAlign');
      case 'zm': return fl.getStyle(m,'zoom');
      default: return fl.getStyle(m,g);
      }
    }

    var bf = o(my,'fl'),
        imFloated = (bf != 'none'),
        fl_fixFloat = null,
        finalSort = function() {};

    // resort children for better float compatibility

    if (FLOAT_RESORT && !fl.canIgnore(my)) {

      // resort floated children for better compatibility

      // copy child list
      var kids = [], left = [], right = [];
      for (var i = 0; i < my.childNodes.length; i++) {
        if (my.childNodes[i].tagName && my.childNodes[i].tagName.match(/ignore/i)) {
          my.removeChild(my.childNodes[i--]);
          continue;
        }
        if (fl.canIgnore(my.childNodes[i]) || my.childNodes[i].fl_placeholder)
          continue;
        kids.push(my.childNodes[i]);
      }

      // find floated children
      for (var i = 0; i < kids.length; i++) {

        var kfl = o(kids[i],'fl');

             if (kfl === (dir = 'left')) left.push(kids[i]);
        else if (kfl === (dir = 'right')) right.push(kids[i]);
        else continue;

        kids[i].fl_floating = dir;
      }

      //  move to the right or left of any adjacent text nodes or other ignorable elements
      //    d === 1 for right
      //    d === 0 for left
      function move(d, my, from) {

        var n, p = from || my, skip;

        do {
          if (!(n = d ? p.nextSibling : p.previousSibling)) break;
          skip = false;
          var s = n.fl_for ? n.fl_for : n;
        while (!skip) { skip = true;
          if (s == my)              break;
          if (s.nodeType === 3)     break;
          if (fl.canIgnore(s))      break;
          if (o(s,'ds') === 'none') break;
          if (o(s,'fl') === 'none') break;
          // default
          skip = false; break;
        } if (skip) p = n; } while (skip);

        if (p != my)
          my.parentNode.insertBefore(my, d ? p.nextSibling : p);
      }

      // create a placeholder
      function phl(my) {
        var ph = document.createElement(FLOAT_PLACEHOLDER_TAG);
        if (FLOAT_PLACEHOLDER_CLASS) ph.className = FLOAT_PLACEHOLDER_CLASS;
        ph.style.display = 'none';
        ph.fl_ignore = 'true';
        ph.fl_for = my;
        my.fl_placeholder = ph;
        my.parentNode.insertBefore(ph, my);
        return ph;
      }

      // move left floats
      for (var i = 0; i < left.length; i++) {
        phl(left[i]);
        move(0,left[i]);
        left[i].removeAttribute('fl_floating');
      }

      // move right floats
      for (var i = 0; i < right.length; i++) {
        phl(right[i]);
        move(0,right[i]);
        right[i].removeAttribute('fl_floating');
      }

      // define undo method

      finalSort = function(my,bf) { /* broken code removed for your convenience */ };
    }

    // fix from bottom to top
    var floatedChild = false;
    for (var i = 0; i < my.childNodes.length; i++) {
      var n = my.childNodes[i];
      if (n.nodeType === 1 && !fl.canIgnore(n))
        floatedChild = fl(n, false, deep + 1) || floatedChild;
      if (fl.stopped) return;
    }

    // Do I need the fix?
    if (!fl.canIgnore(my) &&
        (force || my.floatacious ||
          (my.parentNode &&
          fl.getStyle(my, 'width') === 'auto' &&
          imFloated &&
          floatedChild))) {

      // I do!

      my.floatacious = 'true';

      fl_fixFloat = function(my,bf,finalSort) {

        my.style.width = 'auto'; // Undo previous width assignment

        var pta=null,   // The text-alignment specified in my parent's inline style attribute (if any)
            ptaS=null,  // The inherited or current text-alignment of my parent
            mfl=null,   // my float direction specified in my inline style attribute
            mflS=null,  // my inherited or current float direction
            mds=null,   // my display specified in my inline style attribute
            mzm=null,   // my zoom specified in my inline style attribute
            mta=null,   // my text-alignment specified in my inline style attribute
            mtaS=null;  // my inherited or current text-alignment

        // Back up style properties we might need to mess with

        // parent's text-alignment
        if (my.parentNode.fl_tas) {
          pta = my.parentNode.fl_ta; // The text-alignment specified in the element's inline style attribute
          ptaS = my.parentNode.fl_tas; // The inherited or current CSS text-align of the parent
        } else {
          // first time floatacious is examining this parent
          ptaS = fl.getStyle(my.parentNode, 'textAlign') || 'left';
          my.parentNode.fl_tas = ptaS; // The inherited or current CSS text-align of the parent
          pta = my.parentNode.style.textAlign || 'fl_null';
          my.parentNode.fl_ta = pta; // The text-align specified in the element's inline style attribute
        }

        // my text-alignment
        if (my.fl_tas) {
          mta = my.fl_ta; // The text-alignment specified in the element's inline style attribute
          mtaS = my.fl_tas; // The inherited or current CSS text-align of the parent
        } else {
          // first time floatacious is examining this parent
          mtaS = fl.getStyle(my, 'textAlign') || 'left';
          my.fl_tas = mtaS; // The inherited or current CSS text-align of the parent
          mta = my.style.textAlign || 'fl_null';
          my.fl_ta = mta; // The text-align specified in the element's inline style attribute
        }

        // Need to adjust parent's text align to correctly float me
        if (bf !== ptaS && // If I'm floating in the opposite direction of my parent's text-alignment
          !(bf === 'left' && (ptaS === 'justify' || ptaS === 'center'))) { // let (left == justify == center)

          // We need to srink wrap text around me
          for (var i = 0; i < my.parentNode.childNodes.length; i++) {

            var e, s = my.parentNode.childNodes[i];

            if (s.nodeType === 3) {

              // swap sibling text nodes with inline elements
              e = document.createElement(FLOAT_TEXT_TAG);
              if (FLOAT_TEXT_CLASS) e.className = FLOAT_TEXT_CLASS;
              e.fl_text = 'true';
              e.style.display = 'inline';
              e.style.textAlign = ptaS;
              e.style.styleFloat = 'left';
              my.parentNode.insertBefore(e, s);
              e.appendChild(s);
              fl(e,true,0,true);

            } else {
              e = s;
              if (e.fl_text)
                fl(e,true,0,true); // recalc child text node
            }

            if (fl.canIgnore(e)) continue;

            // Going to test how siblings align their text;
            //  backup sibling text-alignment
            e.fl_ta_sib = fl.getStyle(e, 'textAlign');

          }

          // "Float" us kids to the right
          my.parentNode.style.textAlign = bf;

          // Check for inherited text aligns in siblings and correct if necessary
          for (var i = 0; i < my.parentNode.childNodes.length; i++) {
            var e = my.parentNode.childNodes[i];
            if (!fl.canIgnore(e) && e.fl_ta_sib !== fl.getStyle(e, 'textAlign')) {
              // parent's text-alignment was inherited;
              // use parent's original text-alignment
              if (!e.fl_ta) { // backup
                e.fl_ta = e.style.textAlign || 'fl_null';
                e.fl_tas = e.fl_ta_sib || 'left';
              }
              e.style.textAlign = ptaS;
            }
            e.removeAttribute('fl_ta_sib');
          }
        }

        // Back up more style properties we need to mess with

        // Get my original float direction
        if (my.fl_fl) {
          mfl = my.fl_fl;
          mflS = my.fl_fls;
        } else if (my.style.styleFloat) {
          mfl = my.style.styleFloat || 'fl_null';
          my.fl_fl = mfl;
          mflS = fl.getStyle(my, 'styleFloat');
          my.fl_fls = mflS;
        }

        // Get my original display
        if (my.fl_ds)
          mds = my.fl_ds
        else if (my.style.display) {
          mds = my.style.display || 'fl_null';
          my.fl_ds = mds;
        }

        // Get my original zoom
        if (my.fl_zm)
          mzm = my.fl_zm
        else if (my.style.zoom) {
          mzm = my.style.zoom || 'fl_null';
          my.fl_zm = mzm;
        }

        // get original clear
        if (!my.fl_cl) {
          my.fl_cl = my.style.clear || 'fl_null';
          my.fl_cls = fl.getStyle(my, 'clear');
        }

        // wrap inline child elements for a better guess of their rendered width
        if (!my.fl_text) { // prevent infinite wrapping

          for (var i = 0; i < my.childNodes.length; i++) {

            var f, t = my.childNodes[i];

            if (fl.canIgnore(t)) continue;

            if (!t.fl_text &&
                (t.nodeType === 3 ||                                        // If child is a text node or...
                  (fl.getStyle(t, 'display') === 'inline' &&                // ...an inline element...
                  fl.getStyle(t, 'styleFloat') === 'none' &&                // ...that's unfloated...
                  !t.floatacious && fl.getStyle(t, 'width') === 'auto'))) { // ...and auto-width

              // wrap inline child

              f = document.createElement(FLOAT_TEXT_TAG);
              if (FLOAT_TEXT_CLASS) f.className = FLOAT_TEXT_CLASS;
              f.fl_text = 'true';
              f.style.display = 'inline';
              f.style.textAlign = mtaS;
              f.style.styleFloat = 'left';
              my.insertBefore(f,t);
              f.appendChild(t);
              fl(f, true, 0, true);
              f.style.styleFloat = 'none';

            } else {
              f = t;
              if (f.fl_text)
                fl(f,true,0,true); // recalc child text node
            }

            // backup child text align
            if (!f.fl_ta) {
              f.fl_ta = f.style.textAlign || 'fl_null';
              f.fl_tas = fl.getStyle(f, 'textAlign') || 'left';
            }
          }

          // Check for inherited text aligns in children and correct if necessary
          for (var i = 0; i < my.childNodes.length; i++) {
            var f = my.childNodes[i];
            if (fl.canIgnore(f)) continue;
            if (f.fl_ta_c !== fl.getStyle(f, 'textAlign')) {
              // parent's text-alignment was inherited;
              // use parent's original text-alignment
              if (!f.fl_ta) { // backup
                f.fl_ta = f.style.textAlign || 'fl_null';
                f.fl_tas = f.fl_ta_c || 'left';
              }
              f.style.textAlign = mtaS;
            }
            f.removeAttribute('fl_ta_c');
          }
        }

        var a = fl.all (my, true); //children

        // reset the block display and float for contents
        for (var i = 0; i < a.length; i++) {

          var l = a[i];

          if (l.fl_ignore || l.tagName.match(/ignore/)) continue;

          if (!l.fl_ds) l.fl_ds = l.style.display || 'fl_null';
          if (!l.fl_fl) {
            l.fl_fl = l.style.styleFloat || 'fl_null';
            l.fl_fls = fl.getStyle(l, 'styleFloat');
          }

          if (!l.fl_zm) l.fl_zm = l.style.zoom || 'fl_null';

          // default setting
          l.style.display = 'inline-block';
          l.style.zoom = 1;

          var lfl = l.fl_fls;

          if (lfl !== 'none' &&
              bf !== lfl) {

            // preserve shrinkage when child floated in opposite direction
            my.style.textAlign = lfl;
            if (lfl === 'right')
              l.style.styleFloat = 'none';
            else
              l.style.styleFloat = 'left';
            l.style.display = 'inline';

            var lcl = o(l,'cl');

            if (!l.fl_text && l.parentNode == my && lcl !== 'none') {
              // Emulate clearing for a "floated" inline
              var brBefore = false,
                  brAfter = false;
              if (lcl === 'both' || lcl === 'left') {
                var prev = l.previousSibling;
                while (prev) {
                  if (!fl.canIgnore(l) && (prev.nodeType === 3 || prev.fl_text))
                    break;
                  else if (prev.offsetWidth && o(l,'fl') !== 'none') {
                    brBefore = true;
                    break;
                  }
                  prev = prev.previousSibling;
                }
              }
              if (brBefore) {
                var br = document.createElement('BR');
                br.fl_ignore = 'true';
                br.fl_clear = 'true';
                br.style.styleFloat = bf; // fix sibling absorption
                my.insertBefore(br, l);
              }
              if (lcl === 'both' || lcl === 'right') {
                var next = l.nextSibling;
                while (next) {
                  if (next.nodeType === 3 || next.fl_text)
                    break;
                  else if (!fl.canIgnore(l) && (next.offsetWidth && o(l,'fl') !== 'none')) {
                    brAfter = true;
                    break;
                  }
                  next = next.previousSibling;
                }
              }
              if (brAfter) {
                var br = document.createElement('BR');
                br.fl_ignore = 'true';
                br.fl_clear = 'true';
                br.style.styleFloat = bf; // fix sibling absorption
                my.insertBefore(br, l.nextSibling);
              }
              if (!l.fl_cls) {
                l.fl_cls = lcl;
                l.fl_cl = l.style.clear || 'fl_null';
              }
              if (lcl !== 'both')
                l.style.clear = 'none';
              else
                l.style.clear = lcl;
            }

          } else if (lfl !== 'none' && lfl === bf) {
            if (lfl === 'right')
              l.style.styleFloat = 'none';
            l.style.display = 'inline';
            if (o(l,'cl') !== 'none') {
              l.style.display = 'inline-block';
            }
          } else if (lfl === bf || l.fl_text) {
            l.style.styleFloat = 'none';
          }

        }

        // shrink me
        my.style.zoom = 1;
        my.style.display = 'inline';
        my.style.styleFloat = 'none';
        //my.style.clear = 'both';

        // Correct floating of siblings
        if (!my.parentNode.fl_zm)
          my.parentNode.fl_zm = my.parentNode.style.zoom || 'fl_null';
        my.parentNode.style.zoom = 1;

        // specify my shrunken width
        my.style.width = my.fl_text ? my.offsetWidth + 3 : // TODO: what are the specifics of this text node dimension business? +3 is a stab in the dark
                          fl.getWidth(my);

        if (FLOAT_RESORT)
          finalSort(my, bf);

        // Reset contents' css

        function revert(str) { return str === 'fl_null' ? null : str }

        var mcta = fl.getStyle(my, 'textAlign');
        for (var i = 0; i < a.length; i++) {
          var l = a[i];
          //if (fl.canIgnore(l)) continue;
          // Remove CSS
          if (l.fl_text) {
            l.parentNode.insertBefore(l.childNodes[0], l);
            l.parentNode.removeChild(l);
          } else {
            if (l.fl_ta) {
              fl.removeStyle(l, 'textAlign', revert(l.fl_ta));
              l.removeAttribute('fl_ta');
              l.removeAttribute('fl_tas');
            }
            if (l.fl_fl) {
              fl.removeStyle(l, 'float', revert(l.fl_fl));
              l.removeAttribute('fl_fl');
              l.removeAttribute('fl_fls');
            }
            if (l.fl_ds) {
              fl.removeStyle(l, 'display', revert(l.fl_ds));
              l.removeAttribute('fl_ds');
            }
            /*if (l.fl_zm) {
              fl.removeStyle(l, 'zoom', revert(l.fl_zm));
              l.removeAttribute('fl_zm');
            }*/
            if (l.fl_cl) {
              if (!(bf === 'left' && l.fl_cls === 'both' && fl.getStyle(l, 'styleFloat') === 'right')) {
                fl.removeStyle(l, 'clear', revert(l.fl_cl));
                l.removeAttribute('fl_cl');
                l.removeAttribute('fl_cls');
              } else {
                l.style.clear = 'none';
              }
            }
          }
        }

        // remove inline-clearing breaks
        for (var i = 0; i < my.childNodes.length; i++)
          if (my.childNodes[i].fl_clear)
            my.removeChild(my.childNodes[i--]);

        // Remove CSS

        fl.removeStyle(my.parentNode, 'textAlign', revert(my.parentNode.fl_ta));
        my.parentNode.removeAttribute('fl_ta');
        my.parentNode.removeAttribute('fl_tas');

        fl.removeStyle(my, 'float', revert(my.fl_fl));
        fl.removeStyle(my, 'clear', revert(my.fl_cl));
        //fl.removeStyle(my, 'zoom', revert(my.fl_zm));
        fl.removeStyle(my, 'display', revert(my.fl_ds));
        fl.removeStyle(my, 'textAlign', revert(my.fl_ta));
        my.removeAttribute('fl_fl');
        my.removeAttribute('fl_fls');
        //my.removeAttribute('fl_zm');
        my.removeAttribute('fl_ds');
        my.removeAttribute('fl_ta');
        my.removeAttribute('fl_tas');

      };

    } else if (FLOAT_RESORT) {
      finalSort(my,bf);
    }

    // set timeouts to fire the fix for elements in
    // reverse order of their depth in the DOM

    if (fl_fixFloat && instant)
      fl_fixFloat(my,bf,finalSort); // fix immediately
    else {
      if (my == document.body) {
        // Start queueing fixes for entire document
        var queue = (fl.queue || []).slice(0),
            shal = false,
            depth = 0,
            last = false;
        if (!queue.length) {
          fl.run++;
          if (typeof stan === 'undefined') {
            fl.floating = false;
            if (fl.queued) { fl.queued = false; fl(); }
          }
          return;
        }
        // get deepest child level
        for (var i = 0; i < queue.length; i++) {
          if (queue[i][1] > depth) {
            depth = queue[i][1];
          }
          if (shal === false || queue[i][1] <= shal) {
            shal = queue[i][1];
            last = i;
          }
        }
        f = 1; // delay factor
        for (var i = 0; i < queue.length; i++) {
          if (last === i) {
            var li = i;
            setTimeout(function () { queue[li][0](fl.callback, true); }, (depth - queue[i][1]) * f);
          } else
            setTimeout(queue[i][0], (depth - queue[i][1]) * f);
        }
        fl.queue = [];
      } else if (fl_fixFloat) {
        var queue = fl.queue || [];
        queue[queue.length] = [ function(callback, last) {
          fl_fixFloat(my,bf,finalSort);
          if (callback) callback(FLOAT_RESORT);
          if (last) {
            fl.run++;
            if (typeof stan === 'undefined') {
              floatacious.floating = false;
              if (fl.queued) { fl.queued = false; fl(); }
            }
            FLOAT_RESORT = false; // Don't need to resort again
          }
        }, deep ];
        fl.queue = queue;
      }
    }

    return imFloated;

  };

  fl.version = ver.version;
  fl.timestamp = ver.timestamp;

  // Gets an element's computed pixel width
  fl.getWidth = function(elem) {

    var name = 'width',
        cssShow = { position: "absolute", visibility: "hidden", display:"block" },
        cssWidth = [ "Left", "Right" ],
        rfloat = /float/i,
        val,
        props = cssShow,
        which = cssWidth,
        getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
        rdashAlpha = /-([a-z])/ig,
        rnumpx = /^-?\d+(?:px)?$/i,
        rnum = /^-?\d/,
        fcamelCase = function( all, letter ) {
          return letter.toUpperCase();
        };

    // jQuery
    function curCSS( elem, name, force ) {

      var ret, style = elem.style, filter;

      // Make sure we're using the right name for getting the float value
      if ( rfloat.test( name ) ) {
        name = styleFloat;
      }

      if ( !force && style && style[ name ] ) {
        ret = style[ name ];

      } else if ( getComputedStyle ) {

        // Only "float" is needed here
        if ( rfloat.test( name ) ) {
          name = "float";
        }

        name = name.replace( rupper, "-$1" ).toLowerCase();

        var defaultView = elem.ownerDocument.defaultView;

        if ( !defaultView ) {
          return null;
        }

        var computedStyle = defaultView.getComputedStyle( elem, null );

        if ( computedStyle ) {
          ret = computedStyle.getPropertyValue( name );
        }

        // We should always get a number back from opacity
        if ( name === "opacity" && ret === "" ) {
          ret = "1";
        }

      } else if ( elem.currentStyle ) {
        var camelCase = name.replace(rdashAlpha, fcamelCase);

        ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];

        // From the awesome hack by Dean Edwards
        // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291

        // If we're not dealing with a regular pixel number
        // but a number that has a weird ending, we need to convert it to pixels
        if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
          // Remember the original values
          var left = style.left, rsLeft = elem.runtimeStyle.left;

          // Put in the new values to get a computed value out
          elem.runtimeStyle.left = elem.currentStyle.left;
          style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
          ret = style.pixelLeft + "px";

          // Revert the changed values
          style.left = left;
          elem.runtimeStyle.left = rsLeft;
        }
      }

      return ret;
    }

    // jQuery
    function each(object, callback) {
      for ( var value = object[0], i = 0;
        i < object.length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
    }

    // jQuery
    function getWH() {
      val = name === "width" ? elem.offsetWidth : elem.offsetHeight;

      if (fl.ieVer >= 6) // IE5 needs to return full outerwidth -!
        each( which, function() {
          val -= parseFloat(curCSS( elem, "padding" + this, true)) || 0;
          val -= parseFloat(curCSS( elem, "border" + this + "Width", true)) || 0;
        });
    }

    // jQuery
    function swap( elem, options, callback ) {

      var old = {};

      // Remember the old values, and insert the new ones
      for ( var name in options ) {
        old[ name ] = elem.style[ name ];
        elem.style[ name ] = options[ name ];
      }

      callback.call( elem );

      // Revert the old values
      for ( var name in options ) {
        elem.style[ name ] = old[ name ];
      }
    }

    if ( elem.offsetWidth !== 0 ) {
      getWH();
    } else {
      swap( elem, props, getWH );
    }

    return Math.max(0, Math.round(val));
  };

  fl.canIgnore = function(el) {
    return el.nodeType === 1 ? (el.className.match(/(^|\s)fl_ignore($|\s)/i) || el.tagName.match(/ignore|!/i) || el.fl_ignore) : false;
  };

  // Gather all an element's descendants into an array
  fl.all = function(l, noskip) {
    c = [];
    for (var i = 0; i < l.childNodes.length; i++)
      if (l.childNodes[i].nodeType === 1 && (noskip || !fl.canIgnore(l.childNodes[i]))) {
        c.push(l.childNodes[i]);
        c = c.concat(fl.all(l.childNodes[i], noskip));
      }
    return c;
  };

  // return an elements style attribute as a string
  fl.getStyleString = function(el) {
    var cssString;
    cssString = el.style.cssText;
    if( typeof(cssString) != 'string' ) {
      cssString = el.getAttribute('style');
    }
    return cssString;
  };

  // Removes a style property from an element, unless def is specified
  fl.removeStyle = function(elem, name, def) {

    name = name.replace(/([A-Z])/g, "-$1");
    name = name.toLowerCase();

    /* setStyle function */
    function setStyle(element, styleText){
      if(element.style.setAttribute)
        element.style.setAttribute('cssText', styleText);
      else
        element.setAttribute('style', styleText);
    }

    style = fl.getStyleString(elem);
    re = new RegExp('(^|\\s|;)' + name + '\\s*:[^;]+', 'i');

    if (def) {
      if (style.match(re))
        setStyle(elem, style.replace(re, '$1' + name + ': ' + def));
      else
        setStyle(elem, style + '; ' + def)
    } else
      setStyle(elem, style.replace(re, ''));

  }

  // Get current CSS values for a style property
  fl.getStyle = window.fl.getStyle = function(elem, name) {
    if (!elem.style) return null;
    // J/S Pro Techniques p136
    if (elem.style[name]) {
      return elem.style[name];
    } else if (elem.currentStyle) {
      return elem.currentStyle[name];
    }
    else if (document.defaultView && document.defaultView.getComputedStyle) {
      name = name.replace(/([A-Z])/g, "-$1");
      name = name.toLowerCase();
      s = document.defaultView.getComputedStyle(elem, "");
      return s && s.getPropertyValue(name);
    } else {
      return null;
    }
  };

  fl.IEContentLoaded = function(w, fn) {
    var d = w.document, done = false,
    // only fire once
    init = function () {
      if (!done) {
        done = true;
        fn();
      }
    };
    // polling for no errors
    (function () {
      try {
        // throws errors until after ondocumentready
        d.documentElement.doScroll('left');
      } catch (e) {
        setTimeout(arguments.callee, 50);
        return;
      }
      // no errors, fire
      init();
    })();
    // trying to always fire before onload
    d.onreadystatechange = function() {
      if (d.readyState == 'complete') {
        d.onreadystatechange = null;
        init();
      }
    };
  };

  var script = document.scripts[document.scripts.length - 1];

  fl.loader = function(callback) {

    // Load code inside the script tag itself
    try {
      eval(script.innerHTML);
    } catch (ex) {
      // ignore errors
    }

    // options
    if (typeof FLOAT_RESIZE === 'undefined')
      window.FLOAT_RESIZE = true;
    if (typeof FLOAT_RESORT === 'undefined')
      window.FLOAT_RESORT = true;
    if (typeof FLOAT_PLACEHOLDER_TAG === 'undefined')
      window.FLOAT_PLACEHOLDER_TAG = 'FLPLACEHOLDER';
    if (typeof FLOAT_PLACEHOLDER_CLASS === 'undefined')
      window.FLOAT_PLACEHOLDER_CLASS = '';
    if (typeof FLOAT_TEXT_TAG === 'undefined')
      window.FLOAT_TEXT_TAG = 'FLTEXT';
    if (typeof FLOAT_TEXT_CLASS === 'undefined')
      window.FLOAT_TEXT_CLASS = '';
    if (typeof FLOAT_TEXT_CLASS === 'undefined')
      window.FLOAT_TEXT_CLASS = '';

    // Should I stay or should I go?
    if (fl.stopped || (!(fl.ieVer > 0 && fl.ieVer < 8))) {
      if (callback) callback();
      return;
    }

    // Fix floats
    fl(callback);

    if (FLOAT_RESIZE) {
      // recalc on window resize:
      fl.interval = setInterval(function() {
        if (fl.ieVer >= 8 && fl.ieVer < 9 && !fl.resized) return;
        fl.resize = false;
        if (parseInt(fl.bodyOffsetWidth) !== document.body.offsetWidth ||
            parseInt(fl.bodyOffsetHeight) !== document.body.offsetHeight) {
          fl();
        }
        fl.bodyOffsetWidth = document.body.offsetWidth;
        fl.bodyOffsetHeight = document.body.offsetHeight;
      }, 500);
      window.attachEvent('onresize', function() {
        fl.resized = true;
      });
    }

  };

  // Returns the version of Internet Explorer or a -1
  // (indicating the use of another browser).
  var rv = -1; // Return value assumes failure.
  if (navigator.appName === 'Microsoft Internet Explorer') {
    var ua = navigator.userAgent;
    var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  fl.ieVer = rv;

  // Start fixing on page load
  fl.IEContentLoaded(window, function () {
    if (typeof stan === 'undefined') fl.loader(); // If Stan is present, let Stan load floatacious
  });

})();